package com.iflytek.cosmo.ocr.web.controller;

import javax.servlet.http.HttpServletRequest;
import java.net.URLDecoder;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import com.alibaba.fastjson.JSON;
import com.iflytek.cosmo.ocr.common.config.WorksProperties;
import com.iflytek.cosmo.ocr.common.core.TaskDispatchSystem;
import com.iflytek.cosmo.ocr.common.enums.ResultCodeEnum;
import com.iflytek.cosmo.ocr.common.util.IpAddress;
import com.iflytek.cosmo.ocr.model.domain.MessageOutput;
import com.iflytek.cosmo.ocr.model.domain.OcrResultOutput;
import com.iflytek.cosmo.ocr.model.domain.State;
import com.iflytek.cosmo.ocr.service.FileService;
import com.iflytek.cosmo.ocr.service.RecogniseService;
import com.iflytek.cosmo.ocr.web.vo.CaptureUploadParamVO;
import com.iflytek.cosmo.ocr.web.vo.ModifyRecResultVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

/**
 * 语音助手工具识别服务controller
 * 
 * @author yunsun
 */
@Api("语音助手工具识别服务")
@RestController
@RequestMapping(value = "/tool")
public class RecogniseController {

	/**
	 * 日志记录器
	 */
	private final Logger logger = LoggerFactory.getLogger(RecogniseController.class);

	/**
	 * RecogniseService
	 */
	@Autowired
	private RecogniseService recogniseService;

	@Autowired
	private WorksProperties worksProperties;

    @Autowired
    private FileService fileService;

	/**
	 * 导入文件
	 * 
	 * @param userId 用户id
	 * @param dirId 目录id
	 * @param multipartFile 上传文件列表
	 * @return 消息
	 */
	@ApiOperation(value = "文件导入", httpMethod = "POST")
	@PostMapping(value = "/uploadFile/{userId}/{dirId}")
	public MessageOutput<?> uploadFile(@PathVariable("userId") String userId, @PathVariable("dirId") String dirId,
			@RequestParam("files") MultipartFile multipartFile, HttpServletRequest request) {
		logger.debug("------ 文件导入 ------");
        if (multipartFile.getSize() == 0) {
            return new MessageOutput<>(new State(ResultCodeEnum.INVALID_PARAM));
        }

        if (StringUtils.length(FilenameUtils.getBaseName(multipartFile.getOriginalFilename())) > 70) {
            return new MessageOutput<>(new State(ResultCodeEnum.FILENAME_TOO_LONG.getCode(), "文件名长度不能超过70个字符"));
        }
        
		String ip = IpAddress.getRemoteIpAddr(request);
        return TaskDispatchSystem.getInstance(worksProperties).addTask(userId, dirId, multipartFile, ip);
	}

	@ApiOperation(value = "上传pdf密码", httpMethod = "POST")
	@PostMapping(value = "/pdfpass/{fileId}")
	public MessageOutput<?> uploadPdfPassword(@PathVariable("fileId") String fileId, @RequestParam String password,
            HttpServletRequest request) {
        try {
            // password = URLCodec.decodeUrl(password.getBytes());
            password = URLDecoder.decode(password, "utf-8");
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        return fileService.uploadPdfPassword(fileId, password, IpAddress.getRemoteIpAddr(request));
	}

    @ApiOperation(value = "指定页识别", httpMethod = "POST")
    @PostMapping(value = "/recognize/{fileId}/pages")
    public MessageOutput<?> recognizeSubPages(@PathVariable("fileId") String fileId,
            @RequestParam(required = false) String pageIndex) {
	    // 为空时删除全部子页面
        List<Integer> indexList = null;
        if (StringUtils.isNotBlank(pageIndex)) {
            String[] indexs = pageIndex.split(",");
            indexList = Arrays.stream(indexs).map(Integer::parseInt).collect(Collectors.toList());
        }
        return fileService.recognizeSubPages(fileId, indexList);
    }

    @ApiOperation(value = "查询识别进度", httpMethod = "POST")
    @GetMapping(value = "/recognize/progress/{fileId}")
    public MessageOutput<?> queryRecognizeProcess(@PathVariable("fileId") String fileId) {
        return fileService.queryRecognizeProgress(fileId);
    }

	/**
	 * 查询文件识别结果
	 *
	 * @param fileId 文件id
	 * @return 识别结果
	 */
	@ApiOperation(value = "查询文件识别结果", httpMethod = "POST")
	@PostMapping(value = "/getRecResult")
	public OcrResultOutput getRecResult(@RequestParam("fileId") String fileId) {
		logger.debug("------ 查询文件识别结果 ------");
		OcrResultOutput ocrResultOutput = recogniseService.queryRecResultByFileId(fileId);
		return ocrResultOutput;
	}
	
	/**
	 * 查询文件高级功能识别结果
	 * @param fileId 文件id
	 * @param type 1歪斜校正&自动旋转2图像切边 3分栏切分
	 * @return
	 */
	@ApiOperation(value = "查询文件高级模式下识别结果", httpMethod = "POST")
	@PostMapping(value = "/getAdvanceRecResult")
	public OcrResultOutput getAdvanceRecResult(@RequestParam("fileId") String fileId,@RequestParam("type")Short type) {
		logger.debug("------ 查询文件高级功能识别结果开始, 参数 fileId:{}, type:{}",fileId,type);
		OcrResultOutput ocrResultOutput = recogniseService.queryAdvanceRecResult(fileId, type);
		return ocrResultOutput;
	}

	/**
	 * 进行文件识别
	 * 
	 * @param fileId 文件id
	 * @return 识别结果
	 */
	@ApiOperation(value = "进行文件识别", httpMethod = "POST")
	@PostMapping(value = "/doRecognise")
	public OcrResultOutput doRecognise(@RequestParam("fileId") String fileId) {
		logger.debug("------ 进行文件识别 ------");
		OcrResultOutput ocrResultOutput = recogniseService.doRecByFileId(fileId);
		ocrResultOutput.setResultText(ocrResultOutput.getText());
		return ocrResultOutput;
	}

    @ApiOperation(value = "截图识别", notes = "上传图片返回识别结果, 图片不会保存")
    @PostMapping("/capture/{userId}/{dirId}")
    public MessageOutput<String> captureRecognise(@PathVariable("userId") String userId, @PathVariable("dirId") String dirId,
            @RequestBody CaptureUploadParamVO paramVO, HttpServletRequest request) {
        String imageBase64 = paramVO.getImageBase64();
        if (StringUtils.isBlank(imageBase64)) {
            return MessageOutput.failed(String.class, "imageBase64参数不能为空");
        }
        String ip = IpAddress.getRemoteIpAddr(request);
        return recogniseService.recogniseCapture(userId, dirId, imageBase64, paramVO.getSaveImage(), ip,
                paramVO.getOpration());
    }

    @ApiOperation(value = "根据识别结果获取其中表格的 html", notes = "无表格时返回空")
    @PostMapping("/table/html/{fileId}")
    public MessageOutput<String> viewTableHtml(@PathVariable String fileId) {
        String tableHtml = recogniseService.viewTableHtml(fileId);
        return MessageOutput.success(tableHtml);
    }
    
    @ApiOperation(value = "修改识别区域文本接口", notes = "修改识别区域文本接口")
    @PostMapping("/modifyRecResult")
    public MessageOutput<String> modifyRecResult(@RequestBody ModifyRecResultVO modifyRecResultVO) {
    	logger.debug("修改识别区域文本接口参数 modifyRecResultVO:{}",JSON.toJSONString(modifyRecResultVO));
        return recogniseService.modifyRecResult(modifyRecResultVO);
    }
}
